#include <sys/types.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include "Task.hpp"
static const int nums = 5;
static int num = 0;
struct Channel
{
    Channel(int fd, pid_t child_pid)
        : _fd(fd), _child_id(child_pid)
    {
        _channel_name = "channel-";
        _channel_name += std::to_string(num++);
    }
    int _fd;
    pid_t _child_id;
    std::string _channel_name;
};
void Work(int fd)
{
    while (true)
    {
        int buf = 0;
        int n = read(fd, &buf, sizeof(buf));
        if (n == sizeof(buf))
        {
            _t.run_task(buf); // 执行对应的任务
        }
        else if (n == 0)//写端关闭
        {
            break;
        }
        else
        {
            std::cout<<"接收到了错误的任务码"<<"\n";
        }
    }
}
void CloseWrite(const std::vector<Channel>& vc)
{
    for(auto& channel:vc)
    {
        close(channel._fd);
    }
}
void CreateChannels(std::vector<Channel> *vc)
{
    for (int i = 0; i < nums; i++)
    {
        // 创建管道
        int pipefd[2] = {0};
        int ret = pipe(pipefd);
        assert(ret == 0);
        
        pid_t pid = fork();
        assert(pid >= 0);
        if (pid == 0)
        {
            // child
            close(pipefd[1]);//关闭新开的
            CloseWrite(*vc);//关闭历史的
            // 阻塞式读取，被主控进程控制
            Work(pipefd[0]);
            std::cout<<"进程"<<getpid()<<"退出!"<<"\n";
            exit(0);
        }
        // 父进程
        close(pipefd[0]);
        vc->push_back(Channel(pipefd[1], pid));
    }
}
void SendTasks(const std::vector<Channel> &vc,int flag=0)
{
    if(flag>0)
    {
        while (true)
        {
            for (auto &channel : vc)
            {
                //sleep(1);
                int pos = _t.select_task();
                std::cout << "给" << channel._channel_name << "信道," << channel._child_id << "进程" << "发送了一个任务..." << "\n";
                int n = write(channel._fd, &pos, sizeof(pos));
                assert(n != -1);
                flag--;
                if(flag==0)
                break;
            }
            if(flag==0) break;
        }
    }
    else
    {
        while (true)
        {
            for (auto &channel : vc)
            {
                //sleep(1);
                int pos = _t.select_task();
                std::cout << "给" << channel._channel_name << "信道," << channel._child_id << "进程" << "发送了一个任务..." << "\n";
                int n = write(channel._fd, &pos, sizeof(pos));
                assert(n != -1);
            }
        }
    }
    
}
void ReclaimSlave(const std::vector<Channel>& vc)
{
    for(auto& channel:vc)
    {
        close(channel._fd);
    }
    //wait
    for(auto& channel:vc)
    {
        int n=waitpid(channel._child_id,nullptr,0);
        if(n==channel._child_id)
        std::cout<<channel._child_id<<"进程等待完毕"<<"\n";
    }
}
int main()
{
    std::vector<Channel> vc;
    //创建进程池
    CreateChannels(&vc);
    //轮询式选择信道发送随机任务
    SendTasks(vc,100000);
    //回收子进程
    ReclaimSlave(vc);
    return 0;
}